package com.jihui.user.controller.login;


import com.jihui.security.web.userdetails.CurrentUserDetails;
import com.jihui.user.common.IPUtils;
import com.jihui.user.model.JihuiUser;
import com.jihui.user.model.UserManager;
import org.apache.commons.lang3.StringUtils;
import org.jsondoc.core.annotation.Api;
import org.jsondoc.core.annotation.ApiMethod;
import org.jsondoc.core.annotation.ApiQueryParam;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.actuate.metrics.CounterService;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.web.authentication.RememberMeServices;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;

/**
 * user login
 *
 * @author linux_china
 */
@Controller
@RequestMapping
@Api(description = "登录服务", name = "login", group = "account")
public class LoginController {
    /**
     * 设置cookie的作用域名
     */
    @Value("${info.domain}")
    private String domain;

    @Value("${info.user.domain}")
    private String userDomain;



    @Autowired
    private UserManager userManager;
    @Autowired
    private CounterService counterService;
    @Autowired
    private RememberMeServices rememberMeServices;

    private final static Logger logger = LoggerFactory.getLogger(LoginController.class);

    @RequestMapping("/")
    @ApiMethod(description = "index")
    public String index() {
        return "redirect:/login/index";
    }


    @RequestMapping(value = "/login/index", method = RequestMethod.GET)
    @ApiMethod(id = "login_index", description = "登录首页", summary = "login index")
    @CrossOrigin
    public ModelAndView loginPage(HttpServletRequest request, HttpServletResponse response) {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("login");

        //获得需要跳转的路径
        String redirect = request.getParameter("redirect");
        modelAndView.addObject("redirect", redirect);

        //获取其他地方重定向过来时的错误信息展示，如从微信登陆时跳转回来：你的账户已被冻结
        String error = request.getParameter("error");
        if (error == null) {
            return modelAndView;
        }
        if ("Y20-100101".equals(error)) {
            modelAndView.addObject("error", "错误次数过多，请通过“忘记密码”重置");
        } else if ("Y20-100408".equals(error)) {
            modelAndView.addObject("error", "此账号已被冻结");
        } else {
            modelAndView.addObject("error", "系统错误");
        }
        //注册的跳转
        return modelAndView;
    }



    @ResponseBody
    @RequestMapping(value = "/login/userName", method = RequestMethod.POST)
    @ApiMethod(id = "login", description = "登录", summary = "login")
    public Map login(@ApiQueryParam(name = "username", description = "nickname,email,mobile") @RequestParam String username,
                     @ApiQueryParam(name = "password", description = "user password") @RequestParam String password,
                     @ApiQueryParam(name = "redirect", description = "user redirect") @RequestParam(required = false) String redirect,
                     HttpServletRequest request, HttpServletResponse response) {
        //返回前台的json
        Map<String, Object> result = new HashMap<>();
        String redirect1 = request.getParameter("redirect");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Origin", "*");
        try {
            JihuiUser user = userManager.login(username.trim(), password, IPUtils.getIpAddr(request));
            if (user != null) {
                handleLogin(user, redirect, request, response, result);
            } else {
                result.put("error", "用户名或密码错误");
            }
            return result;
        } catch (Exception e) {
            if (e.getMessage().equals("Y20-100404") || e.getMessage().equals("Y20-100405")) {
                counterService.increment("login error" + username);
                result.put("error", "用户名或密码错误");
            } else if (e.getMessage().equals("Y20-100101")) {
                result.put("error", "错误次数过多，请通过“忘记密码”重置");
            } else if (e.getMessage().equals("Y20-100408")) {
                result.put("error", "此账号已被冻结");
            }
        }
        result.put("result", false);
        return result;
    }


    private void handleLogin(JihuiUser user, String redirect, HttpServletRequest request, HttpServletResponse response, Map result) {
        try {
            CurrentUserDetails currentUserDetails = new CurrentUserDetails(user);
            UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(currentUserDetails, currentUserDetails.getPassword(), currentUserDetails.getAuthorities());
            HttpServletResponseWrapper wrapper = new HttpServletResponseWrapper(response) {
                @Override
                public void addCookie(Cookie cookie) {
                    if (cookie.getDomain() == null) {
                        cookie.setDomain(domain);
                    }
                    cookie.setPath("/");
                    cookie.setMaxAge(3600 * 8);
                    super.addCookie(cookie);
                }
            };
            rememberMeServices.loginSuccess(request, wrapper, authentication);
            //通过账户获得用户的信息
            //wrapper.addCookie(new Cookie("nickname", URLEncoder.encode(user.getDisplayName(), "UTF-8")));
            wrapper.addCookie(new Cookie("headImg", user.getHeadImg() == null ? "" : user.getHeadImg()));
            result.put("result", true);

            if (StringUtils.isEmpty(redirect)) {
                if (user.getAuthoritiesText().contains("ROLE_BUYER")) {
                    result.put("redirect", userDomain);
                } else {
                    result.put("redirect", "http://" + domain);
                }
            } else {
                redirect = URLDecoder.decode(redirect, "UTF-8");
                result.put("redirect", redirect);
            }
        } catch (UnsupportedEncodingException e) {
            logger.error("编解码出错", e.getCause());
        }

    }
}
